package codechicken.wirelessredstone.core;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.TreeMap;

public class ConfigTag
{	
	public ConfigTag(ConfigTag parent, String name)
	{
		parenttag = parent;
		parentfile = parent.parentfile;
		this.name = name;
		qualifiedname = parent.qualifiedname+"."+name;
		parent.childtags.put(name, this);
	}
	
	public ConfigTag(ConfigFile parent, String name)
	{
		parentfile = parent;
		this.name = name;
		qualifiedname = name;
		parentfile.maintags.put(name, this);
		newline = true;
	}
	
	public ConfigTag getTag(String tagname)
	{
		int dotpos = tagname.indexOf(".");
		String maintagname = dotpos == -1 ? tagname : tagname.substring(0, dotpos);
		ConfigTag basetag = childtags.get(maintagname);
		if(basetag == null)
		{
			basetag = new ConfigTag(this, maintagname);
			parentfile.saveConfig();
		}
		if(dotpos == -1)
		{
			return basetag;
		}
		else
		{
			return basetag.getTag(tagname.substring(dotpos+1));
		}
	}
	
	public void setValue(String value)
	{
		this.value = value;
		parentfile.saveConfig();
	}
	
	public void setIntValue(int i)
	{
		setValue(Integer.toString(i));
	}
	
	public void setBooleanValue(boolean b)
	{
		setValue(Boolean.toString(b));
	}
	
	public void setHexValue(int i)
	{
		setValue(Long.toString(((long)i) << 32 >>> 32, 16));
	}
	
	public String getValue()
	{
		return value;
	}
	
	public int getIntValue()
	{
		return Integer.parseInt(getValue());
	}
	
	public int getIntValue(int defaultvalue)
	{
		if(value == null)
		{
			setIntValue(defaultvalue);
		}
		try
		{
			return getIntValue();
		}
		catch(NumberFormatException nfe)
		{
			setIntValue(defaultvalue);
			return getIntValue();
		}
	}
	
	public boolean getBooleanValue()
	{
		String value = getValue();
		if(value != null && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")))
		{
			return true;
		}
		else if(value != null && (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")))
		{
			return false;
		}
		throw new NumberFormatException(value);
	}
	
	public boolean getBooleanValue(boolean defaultvalue)
	{
		if(value == null)
		{
			setBooleanValue(defaultvalue);
		}
		try
		{
			return getBooleanValue();
		}
		catch(NumberFormatException nfe)
		{
			setBooleanValue(defaultvalue);
			return getBooleanValue();
		}
	}

	public int getHexValue()
	{
		return (int) Long.parseLong(getValue(), 16);
	}
	
	public int getHexValue(int defaultvalue)
	{
		if(value == null)
		{
			setHexValue(defaultvalue);
		}
		try
		{
			return getHexValue();
		}
		catch(NumberFormatException nfe)
		{
			setHexValue(defaultvalue);
			return getHexValue();
		}
	}

	public void save(FileOutputStream fout, int tabs, String bracequalifier)
	{
		String unqualifiedname = qualifiedname;
		if(qualifiedname.contains(".") && !bracequalifier.equals(""))
		{
			unqualifiedname = qualifiedname.substring(bracequalifier.length() + 1);
		}
		if(newline)
		{
			ConfigFile.writeLine(fout, "", tabs);
		}
		if(comment != null && !comment.equals(""))
		{
			String[] comments = comment.split(":");
			for(int i = 0; i < comments.length; i++)
			{
				ConfigFile.writeLine(fout, "#"+comments[i], tabs);
			}
		}
		if(brace && childtags.size() > 0)
		{
			ConfigFile.writeLine(fout, unqualifiedname, tabs);
			ConfigFile.writeLine(fout, "{", tabs);
			ConfigFile.saveTagTree(fout, childtags, tabs+1, qualifiedname);
			ConfigFile.writeLine(fout, "}", tabs);
		}
		else if(childtags.size() > 0)
		{
			ConfigFile.saveTagTree(fout, childtags, tabs, bracequalifier);
		}
		else if(value != null && !value.equals(""))
		{
			ConfigFile.writeLine(fout, unqualifiedname+"="+value, tabs);
		}
	}	

	public ConfigTag useBraces()
	{
		brace = true;
		parentfile.saveConfig();
		return this;
	}
	
	public ConfigTag setComment(String string)
	{
		comment = string;
		parentfile.saveConfig();
		return this;
	}
	
	public ConfigTag setPosition(int pos)
	{
		position = pos;
		parentfile.saveConfig();
		return this;
	}
	
	public void loadChildren(FileInputStream fin)
	{
		String comment = "";
		String bracequalifier="";
		while(!ConfigFile.EOF)
		{
			String line = ConfigFile.readLine(fin);
			if(line.startsWith("#"))
			{
				if(comment == null || comment.equals(""))
				{
					comment = line.substring(1);
				}
				else
				{
					comment = comment+":"+line.substring(1);
				}
			}
			else if(line.contains("="))
			{
				String qualifiedname = line.substring(0, line.indexOf("="));
				getTag(qualifiedname)
				.setComment(comment)
				.setValue(line.substring(line.indexOf("=")+1));
				comment = "";
				bracequalifier = "";
			}
			else if(line.equals("{"))
			{
				getTag(bracequalifier).setComment(comment).useBraces().loadChildren(fin);
				comment = "";
				bracequalifier = "";
			}
			else if(line.equals("}"))
			{
				return;
			}
			else
			{
				bracequalifier = line;
			}
		}
	}
	
	ConfigFile parentfile;
	ConfigTag parenttag;
	TreeMap<String, ConfigTag> childtags = new TreeMap<String, ConfigTag>();
	String name;
	String qualifiedname;
	String comment;
	String value;
	boolean brace;
	boolean newline;
	int position = Integer.MAX_VALUE;
}
